﻿using FlexFlow.Base.Interface;
using FlexFlow.Model;
using MongoDB.Bson;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FlexFlow.DataProvider.MongoDB
{
    /// <summary>
    /// 为基于MongoDb的用户数据存储器提供实现
    /// </summary>
    public sealed class MongoDbUserProvider : MongoDBPhysicalModelProvider<User>, IUserProvider
    {
        /// <summary>
        /// 使用默认设置创建一个新的用户实例
        /// </summary>
        /// <returns>
        /// 创建的用户实例
        /// </returns>
        public override User Create()
        {
            return new User()
            {
                Locked = false
            };
        }
        /// <summary>
        /// 取得具有指定用户名的用户实体
        /// </summary>
        /// <param name="account">
        /// 用来取得实体的用户名
        /// </param>
        /// <returns>
        /// 取得的用户实体，若实体不存在，则返回null
        /// </returns>
        public User Get(string account)
        {
            IMongoCollection<User> col = mongoDatabase.GetCollection<User>((typeof(User)).Name);
            FilterDefinition<User> filter = (FilterDefinition<User>)(m => m.Account == account);
            return col.FirstOrDefault(filter);
        }
        /// <summary>
        /// 检查指定用户名是否已经存在
        /// </summary>
        /// <param name="account">
        /// 要检查的用户名
        /// </param>
        /// <returns>
        /// 一个表示是否存在的值
        /// </returns>
        public bool CheckAccountExisted(string account)
        {
            IMongoCollection<User> col = mongoDatabase.GetCollection<User>((typeof(User)).Name);
            FilterDefinition<User> filter = (FilterDefinition<User>)(m => m.Account == account);
            return col.FirstOrDefault(filter) != null;
        }

        /// <summary>
        /// 检查指定的email是否已被注册
        /// </summary>
        /// <param name="email">
        /// 要检查的email
        /// </param>
        /// <returns>
        /// 一个表示email是否已经被注册的值
        /// </returns>
        public bool CheckEmailExisted(string email)
        {
            IMongoCollection<User> col = mongoDatabase.GetCollection<User>((typeof(User)).Name);
            FilterDefinition<User> filter = (FilterDefinition<User>)(m => m.Email == email);
            return col.FirstOrDefault(filter) != null;
        }
        /// <summary>
        /// 重命名指定用户
        /// </summary>
        /// <param name="identity">
        /// 用户ID
        /// </param>
        /// <param name="newName">
        /// 新名称
        /// </param>
        /// <returns>
        /// 一个表示是否重命名成功的值
        /// </returns>
        public bool Rename(Guid identity, string newName)
        {
            UpdateDefinition<User> upDef = Builders<User>.Update.Set(m => m.Name, newName);
            return Update(identity, upDef);
        }

        /// <summary>
        /// 更新用户信息
        /// </summary>
        /// <param name="identity">
        /// 要更新的用户的ID
        /// </param>
        /// <param name="name">
        /// 新名称
        /// </param>
        /// <param name="account">
        /// 新账号
        /// </param>
        /// <param name="email">
        /// 新Email
        /// </param>
        /// <param name="isLock">
        /// 是否锁定
        /// </param>
        /// <returns>
        /// 一个表示更新是否成功的值
        /// </returns>
        public bool Update(Guid identity, string name = null, string account = null, string email = null, bool? isLock = null)
        {
            UpdateDefinition<User> upDef = null;
            if (name != null)
            {
                upDef = BuildUpdateDef(m => m.Name, name, upDef);
            }
            if (account != null)
            {
                upDef = BuildUpdateDef(m => m.Account, account, upDef);
            }
            if (email != null)
            {
                upDef = BuildUpdateDef(m => m.Email, email, upDef);
            }
            if (isLock != null)
            {
                upDef = BuildUpdateDef(m => m.Locked, (bool)isLock, upDef);
            }


            if (upDef == null)
            {
                return true;
            }
            else
            {
                return Update(identity, upDef);
            }
        }

        /// <summary>
        /// 更改指定用户的密码
        /// </summary>
        /// <param name="identity">
        /// 要更改密码的用户ID
        /// </param>
        /// <param name="newPwd">
        /// 要更改的新密码
        /// </param>
        /// <returns>
        /// 一个表示密码是否更改成功的值
        /// </returns>
        public bool ChangePassword(Guid identity, string newPwd)
        {
            UpdateDefinition<User> upDef = Builders<User>.Update.Set(m => m.Password, newPwd);
            return Update(identity, upDef);
        }

        /// <summary>
        /// 通过用户姓名查询用户信息(Like模糊查询)
        /// </summary>
        /// <param name="nameLike">
        /// 要查询的用户姓名
        /// </param>
        /// <param name="limit">
        /// 返回结果的限制数量
        /// </param>
        /// <param name="skip">
        /// 返回结果的跳过数量
        /// </param>
        /// <returns>
        /// 查询到的结果
        /// </returns>
        public List<User> QueryByName(string nameLike, int skip = 0,int limit = 10)
        {
            IMongoCollection<User> col = GetCollection();
            FindOptions<User> findOpt = new FindOptions<User>()
            {
                Skip = skip,
                Limit = limit
            };
            return col.QueryByName(nameLike, findOpt);
        }
    }
}
